﻿using System;
using System.IO;
using System.IO.Pipes;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Net.Sockets;
using System.Net;
using System.Text;
using System.Runtime.Remoting.Messaging;

namespace ConsoleApplication1
{

    //this calles is to store all the information needed to track a gps users
    class user
    {
        double Lat;
        double Log;
        long time;
        int state;
        double speed;
        public String Lines;

        public user()
        {
            Lat = 0;
            Log = 0;
            state = 0;
            speed = 0;
            time = 0;
            Lines = "";
        }

        public void setLat(double x)
        {
            this.Lat = x;
        }

        public void setLog(double x)
        {
            this.Log = x;
        }

        public void setTime(long x)
        {
            this.time = x;
        }

        public void setState(int x)
        {
            this.state = x;
        }

        public void setspeed(double x)
        {
            this.speed = x;
        }

        public void addline(string line)
        {
            this.Lines = this.Lines + line;
        }

        public void printline()
        {
            Console.WriteLine(this.Lines);
        }
    }




    class Program
    {

        static double curLat;
        static double curLon;
        static long curTime;

        
        public static user user1 = new user();



        // this class uses the RTD GIS server to find if the gps cordinate intercepts a rtd resources. 
        static private void CalIntersec()
        {

            NamedPipeServerStream spipe = new NamedPipeServerStream("GPSPipe", PipeDirection.InOut);
           
            double lat = -104.96783;
            double lon = 39.686376;

            //this url will superimpose the gps point on the gis map from rdt with a 3 conical foot buffer.
            //string URL = string.Concat("http://maps.rtd-denver.com/ArcGIS/rest/services/Geometry/GeometryServer/buffer?geometries=", lat.ToString(), "%2c", lon.ToString(), "&inSR=4269&outSR=102113&bufferSR=4269&distances=.001&unit=&unionResults=false&f=json");

            string URL = "http://maps.rtd-denver.com/ArcGIS/rest/services/Geometry/GeometryServer/buffer?geometries=-104.96783%2c39.686376&inSR=4269&outSR=102113&bufferSR=4269&distances=.001&unit=&unionResults=false&f=json";

            WebRequest GetURL;
            GetURL = WebRequest.Create(URL);

            Stream oStream;
            oStream = GetURL.GetResponse().GetResponseStream();


            StreamReader oReader = new StreamReader(oStream);

            string sLine = "";
            string reply = "";
            int i = 0;
            //read in the stream
            while (sLine != null)
            {
                i++;
                sLine = oReader.ReadLine();

                if (sLine != null)
                    reply = string.Concat(reply, sLine);

            }

            //remove the beinging and the end of the reply so that only the needed information is in the string
            reply = reply.Substring(15);
            reply = reply.TrimEnd('}');
            reply = reply.TrimEnd(']');
            Console.WriteLine(reply);

            URL = string.Concat("http://maps.rtd-denver.com/ArcGIS/rest/services/SystemMapLiteGoogleVectors_Future/MapServer/1/query?text=&geometry=", reply, "&geometryType=esriGeometryPolygon&inSR=&spatialRel=esriSpatialRelIntersects&where=&returnGeometry=false&outSR=&outFields=&f=pjson");


            GetURL = WebRequest.Create(URL);
            oStream = GetURL.GetResponse().GetResponseStream();
            oReader = new StreamReader(oStream);

            sLine = "";
            reply = "";
            i = 0;

            while (sLine != null)
            {
                i++;
                sLine = oReader.ReadLine();

                if (sLine != null)
                    reply = string.Concat(reply, sLine);

            }

            Parse(reply);
            user1.printline();

            
            byte[] output = new byte[reply.Length * sizeof(char)];
            System.Buffer.BlockCopy(reply.ToCharArray(), 0, output, 0, output.Length);

        int len = output.Length;
        if (len > UInt16.MaxValue)
        {
            len = (int)UInt16.MaxValue;
        }

        try
        {
            if(spipe.IsConnected)
            spipe.Write(output, 0, len);
 
        }
        catch (InvalidOperationException e)
        {
            Console.WriteLine("e");
        }
    
        }

        static private void Parse(String reply)
        {
            if (reply.Contains("C-Line"))
                user1.addline("C");

            if (reply.Contains("D-Line"))
                user1.addline("D");

            if (reply.Contains("E-Line"))
                user1.addline("E");

            if (reply.Contains("F-Line"))
                user1.addline("F");

            if (reply.Contains("H-Line"))
                user1.addline("H");

            if (reply.Contains("W-Line"))
                user1.addline("W");

        }

        static private void Server()
        {
            String recived;
            String[] listRecived;
            IPAddress ipAddress = Dns.GetHostEntry("localhost").AddressList[0];
            TcpListener serverS = new TcpListener(ipAddress, 80);

            serverS.Start();
            Console.WriteLine(" >> Server Started");

            Socket clientSocket = serverS.AcceptSocket();
            Stream strm = new NetworkStream(clientSocket);
            StreamReader reader = new StreamReader(strm);

            while (clientSocket.Connected)
            {

                try
                {
                    //the form of the message recived is LAT,LONG,TIMEinMelSec
                    recived = reader.ReadLine();
                    Console.WriteLine(recived);
                    listRecived = recived.Split(',');
                    curLat = Convert.ToDouble(listRecived[0]);
                    curLon = Convert.ToDouble(listRecived[1]);
                    curTime = Convert.ToInt64(listRecived[2]);

                }
                catch (IOException)
                {
                    break;
                }


            };


            clientSocket.Close();
            serverS.Stop();
            Console.WriteLine(" >> exit");
            Console.ReadLine();

        }


        static void Main(string[] args)
        {

            Thread TestThread1 = new Thread(Server);
            Thread TestThread2 = new Thread(CalIntersec);

            TestThread1.Start();
           // TestThread2.Start();

            Console.Read();
        }


        //using formula found at http://www.geodatasource.com/developers/c-sharp
        private double distance(double lat1, double lon1, double lat2, double lon2)
        {

            double theta = lon1 - lon2;
            double dist = Math.Sin(lat1 * Math.PI / 180.0) * Math.Sin(lat2 * Math.PI / 180.0) + Math.Cos(lat1 * Math.PI / 180.0) * Math.Cos(lat2 * Math.PI / 180.0) * Math.Cos(theta * Math.PI / 180.0);
            dist = Math.Acos(dist);
            dist = (dist * Math.PI / 180.0); ;
            dist = (dist * 60 * 1.1515) / 5280;

            return (dist);
        }



    }
}
